home *** CD-ROM | disk | FTP | other *** search
- Subject: v12i048: Find printable strings in COFF files
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: Tom Reynolds <kiwi!reynolds>
- Posting-number: Volume 12, Issue 48
- Archive-name: strings.coff
-
- Strings finds ascii text strings in binary files, similar to the
- Berkely strings(8) program. This strings understands the Common
- Object File Format (COFF) used by System V.
-
- [ The Makefile will have to be tweaked for non-Microport Unices. --r$ ]
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # Readme Makefile strings.c strings.8
- export PATH; PATH=/bin:/usr/bin:$PATH
- echo shar: "extracting 'Readme'" '(303 characters)'
- if test -f 'Readme'
- then
- echo shar: "will not over-write existing file 'Readme'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Readme'
- XStrings has been developed and tested on a AT-clone running
- XMicroport System V/AT 2.2 but should work on any SysV
- Xenvironment.
- X
- X-------
- X
- XTom Reynolds voice: (205) 721-1200 x 303
- XPhoenix microsystems, inc. uucp: ..!uunet!ingr!kiwi!reynolds
- X991 Discovery Drive
- XHuntsville, AL 35806
- SHAR_EOF
- if test 303 -ne "`wc -c < 'Readme'`"
- then
- echo shar: "error transmitting 'Readme'" '(should have been 303 characters)'
- fi
- fi
- echo shar: "extracting 'Makefile'" '(430 characters)'
- if test -f 'Makefile'
- then
- echo shar: "will not over-write existing file 'Makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- XCFLAGS=-Ml -O
- XLDFLAGS=-Ml
- Xstrings: strings.c
- X cc -o strings $(LDFLAGS) strings.c -lld
- Xinstall: strings
- X strip strings
- X mv strings /usr/local/bin
- X cd /usr/local/bin; chmod 755 strings; chgrp sys strings; chown root strings
- X cp strings.8 /usr/man/man8/strings.8
- X cd /usr/man/man8; chmod 755 strings.8; chgrp sys strings.8; chown root strings.8
- X touch install
- Xstrings.shar:
- X shar -a Readme Makefile strings.c strings.8 >strings.shar
- SHAR_EOF
- if test 430 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: "error transmitting 'Makefile'" '(should have been 430 characters)'
- fi
- fi
- echo shar: "extracting 'strings.c'" '(7898 characters)'
- if test -f 'strings.c'
- then
- echo shar: "will not over-write existing file 'strings.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'strings.c'
- X/*========================================================================*
- X * STRINGS(8) -- Find strings in COFF files *
- X * *
- X * Copyright (c) 1987 *
- X * Tom Reynolds *
- X * Phoenix microsystems, inc. *
- X * 991 Discovery Drive *
- X * Huntsville, AL 35807 *
- X * *
- X * Permission granted to publish in source and object form. *
- X * Publication must retain all copyright notices. *
- X * Object-only distribution permitted only if source is also *
- X * available from distributor. *
- X * Fees are limited to cost-of-media charges. *
- X * *
- X *========================================================================*/
- X
- X#include <stdio.h>
- X#include <filehdr.h>
- X#include <scnhdr.h>
- X#include <ldfcn.h>
- X#include <varargs.h>
- X#include <ctype.h>
- X
- X#define OPTIONS "an:o" /* GETOPT(3C) Option string */
- X
- Xchar *copyright =
- X"Copyright (c) 1987 by Tom Reynolds, Phoenix microsystems, inc. Huntsville AL";
- X
- Xextern char
- X *optarg; /* GETOPT(3C): Current argument */
- X
- Xextern int
- X getopt(), /* GETOPT(3C): Declaration */
- X optind; /* GETOPT(3C): argv[0] index */
- X
- Xextern long
- X ftell(); /* FTELL() calls this */
- X
- Xchar
- X *fn, /* Current file name being processed */
- X *me, /* Process name (from argv[0]) */
- X *options = OPTIONS; /* Command line option string */
- X
- Xint
- X length = 4, /* Need this many to make string */
- X multi = 0; /* True if more than 1 input file */
- X offset = 0; /* True if file offset wanted */
- X
- Xlong
- X types = STYP_DATA; /* Section types to search */
- X
- XLDFILE
- X *ldptr; /* COFF File pointer */
- X
- X/*========================================================================*
- X * error: Write fatal error text and exit *
- X *========================================================================*/
- X
- X/*VARARGS*/
- Xvoid
- Xerror( va_alist )
- Xva_dcl
- X{
- X va_list args; /* Argument list keeper */
- X char *fmt; /* Printf()-like format address */
- X va_start( args ); /* Init the varargs mechanism */
- X fmt = va_arg( args, char * ); /* Pick off format */
- X (void) fprintf( stderr, "%s: ", me );/* Write our process name */
- X (void) vfprintf( stderr, fmt, args );/* Write message text */
- X (void) fputc( '\n', stderr ); /* Terminate the line */
- X va_end( args ); /* Clean up stack */
- X exit( 1 ); /* Back to real world */
- X}
- X/*ARGSUSED*/
- X
- X/*========================================================================*
- X * usage: Tell how to use us *
- X *========================================================================*/
- X
- Xvoid
- Xusage( s )
- Xchar *s; /* Optional error text */
- X{
- X if( s != (char *) NULL ) (void) fprintf( stderr, "%s: %s\n", me, s );
- X (void) fprintf( stderr, "usage: %s [-a] [-n #] [-o] file...\n", me );
- X (void) exit( 1 );
- X}
- X
- X/*========================================================================*
- X * strings: Find and output all strings in this section of file *
- X *========================================================================*/
- X
- Xvoid
- Xstrings( cnt )
- Xlong cnt; /* Bytes in this section */
- X{
- X register int c; /* Character we're considering */
- X char buf[ BUFSIZ+1 ]; /* Holding area for string */
- X register char *bp; /* Walks down buf[] */
- X register char *eob = buf+BUFSIZ; /* End of buffer */
- X int n; /* Length of our string in buf[] */
- X for( bp = buf; cnt != 0L; cnt-- ) {
- X c = GETC( ldptr ); /* Get a character */
- X if( c == -1 ) break; /* Get out if end of file */
- X if( isprint( c ) ) {
- X /* Found a printable character */
- X if( bp != eob ) *bp++ = c;
- X } else if( (c == '\0') || (c == '\n') ) {
- X /* Found a proper terminator, so have string if long enough */
- X n = bp - buf; /* How long is it? */
- X if( n >= length ) {
- X /* String passes */
- X *bp = '\0'; /* End the string */
- X if( multi ) (void) printf( "%s\t", fn );
- X if( offset )
- X (void) printf( "%#lo\t", FTELL( ldptr ) - (long) n - 1L );
- X (void) printf( "%s\n", buf ); /* Show it */
- X }
- X bp = buf; /* Start string over again */
- X } else bp = buf; /* Strings doesn't end right */
- X }
- X}
- X
- X/*========================================================================*
- X * process: Find strings in a single COFF object *
- X *========================================================================*/
- X
- Xvoid
- Xprocess()
- X{
- X if( ISCOFF( TYPE( ldptr ) ) ) {
- X unsigned short section; /* Which section we're working on */
- X struct scnhdr hdr; /* Section header storage */
- X long here; /* Progress into file so far */
- X if( FSEEK( ldptr, (long) HEADER( ldptr ).f_opthdr, 0 ) == -1 )
- X error( "Could not skip optional header in file \"%s\"", fn );
- X here = FTELL( ldptr ) +
- X (sizeof( struct scnhdr ) * HEADER( ldptr ).f_nscns);
- X for( section = 1; section <= HEADER( ldptr ).f_nscns; section++ ) {
- X if( ldshread( ldptr, section, &hdr ) == FAILURE )
- X error( "Could not read section %d's section header in file \"%s\"",
- X section, fn );
- X if( FSEEK( ldptr, here, 0 ) == -1 ) {
- X error( "Could not seek to data segment %d in file \"%s\"",
- X section, fn );
- X }
- X if( hdr.s_flags & types )
- X strings( hdr.s_size ); /* Find the strings */
- X else if( FSEEK( ldptr, hdr.s_size, 0 ) == -1 ) {
- X error( "Could not step over section %d's data area in file \"%s\"",
- X section, fn );
- X }
- X here = FTELL( ldptr ); /* Remember data for next section */
- X }
- X } else {
- X /* Not a COFF file, so do the best we can */
- X if( FSEEK( ldptr, 0L, 0 ) == -1 )
- X error( "Could not seek beginning of file \"%s\"", fn );
- X strings( -1L );
- X }
- X}
- X
- X/*========================================================================*
- X * main: Central Control Logic *
- X *========================================================================*/
- X
- Xint
- Xmain( argc, argv )
- Xint argc; /* Number of arguments */
- Xchar **argv; /* Command line arguments */
- X{
- X int c; /* Command line option character */
- X int errflag = 0; /* Command line error flag */
- X me = argv[ 0 ]; /* Save our process name */
- X while( (c = getopt( argc, argv, options )) != EOF ) {
- X switch( c ) {
- X default: fprintf( stderr, "%s: No -%c yet!\n", me, c ); /*FALLTHRU*/
- X case '?': errflag++; break;
- X case 'a': types |= STYP_TEXT; break;
- X case 'n': length = atoi( optarg ); break;
- X case 'o': offset = 1; break;
- X }
- X }
- X if( errflag > 0 ) usage( "Illegal switches" );
- X if( length < 1 ) usage( "-n spec too short" );
- X if( length > BUFSIZ ) usage( "-n too long" );
- X switch( argc - optind ) {
- X case 0: usage( "Need input filenames" ); /* No files! */
- X case 1: break; /* Only one file */
- X default: multi = 1; break; /* Lotsa files */
- X }
- X if( optind >= argc ) usage( "Need input filenames" );
- X while( optind < argc ) {
- X /* For every input file */
- X fn = optarg = argv[ optind++ ]; /* Get another filename */
- X ldptr = (LDFILE *) NULL; /* Start clean */
- X do {
- X if( (ldptr = ldopen( fn, ldptr )) != (LDFILE *) NULL ) {
- X process();
- X } else {
- X fprintf( stderr, "%s: Cannot open %s\n", me, fn );
- X errflag++;
- X }
- X } while( ldclose( ldptr ) == FAILURE );
- X }
- X (void) exit( errflag ? 1 : 0 );
- X /* NOTREACHED */
- X}
- SHAR_EOF
- if test 7898 -ne "`wc -c < 'strings.c'`"
- then
- echo shar: "error transmitting 'strings.c'" '(should have been 7898 characters)'
- fi
- fi
- echo shar: "extracting 'strings.8'" '(1562 characters)'
- if test -f 'strings.8'
- then
- echo shar: "will not over-write existing file 'strings.8'"
- else
- sed 's/^X//' << \SHAR_EOF > 'strings.8'
- X.TH STRINGS 8
- X.SH NAME
- Xstrings \- find printable strings in files
- X.SH SYNOPSIS
- X.B strings
- X.B " [ " -a " ] "
- X.B " [ " "-n\ #" " ] "
- X.B " [ " -o " ] "
- X.RB ... file ...
- X.SH DESCRIPTION
- X.PP
- X.B Strings
- Xdisplays ascii strings contained in the named input files.
- XThe input files may be either ordinary files or
- X.B COFF
- Xobject files.
- XFor ordinary files, the entire file is searched for strings.
- XCOFF files have only their
- X.B .data
- Xsections searched unless the
- X.B -a
- Xoption is used which also searches any
- X.B .text
- Xsections.
- X.PP
- XThe strings extracted by
- X.B strings
- Xare defined to be a sequence of at least 4 (by default) printable
- Xcharacters terminated by either a
- X.B NULL
- Xor a
- X.BR NEWLINE .
- XThe
- X.B -n #
- Xoption changes the minimum number of characters.
- XFrom 1 to
- X.B BUFSIZ
- Xcharacters are possible.
- X.PP
- XThe
- X.B -o
- Xswitch causes
- X.B strings
- Xto prefix each output line with the octal offset within the file
- X(which is probably not the COFF memory address).
- X.SH "IN MEMORIUM"
- X.B Strings
- Xhas been modeled after the Berkeley strings(1) tool.
- XIt is not a Berkeley product.
- X.SH COPYRIGHT
- X.PP
- X.B Strings
- Xis copyright 1987 by Tom Reynolds.
- XPermission is hereby granted to publish
- X.B strings
- Xin source or object form as long as all copyright notices are
- Xretained.
- XObject\-only distributions are permitted only if the source is also
- Xfreely available from the distributor.
- XAny fee charged for such publication may consist only of a
- Xreasonable charge for any media used.
- X.SH AUTHOR
- X.PP
- XTom Reynolds
- X.br
- XPhoenix microsystems, inc.
- X.br
- X991 Discovery Drive
- X.br
- XHuntsville, AL 35806
- SHAR_EOF
- if test 1562 -ne "`wc -c < 'strings.8'`"
- then
- echo shar: "error transmitting 'strings.8'" '(should have been 1562 characters)'
- fi
- fi
- exit 0
- # End of shell archive
-
- ---------
-
- Tom Reynolds voice: (205) 721-1200 x 303
- Phoenix microsystems, inc. uucp: ..!uunet!ingr!kiwi!reynolds
- 991 Discovery Drive
- Huntsville, AL 35806
- --
- Tom Reynolds voice: (205) 721-1200 x 303
- Phoenix microsystems, inc. uucp: ..!uunet!ingr!kiwi!reynolds
- 991 Discovery Drive
- Huntsville, AL 35806
-
-